<?php

namespace app\controller\test;


use app\model\content\ContentBlogModel;
use app\service\Cache\Cache;
use app\service\BangCache;

class MyCache extends Base
{
	// TODO 缓存原理测试
	//   自己的缓存方法，用户制作缓存
	
	/**
	 *
	 * 绑定原理
	 *  1、设置缓存字段
	 *  2、缓存数据（列表与详情）中匹配这些字段的数据，组合绑定的缓存key
	 *  3、设置缓存数据的文件，缓存数据，同时将缓存文件与绑定生成绑定缓存
	 *
	 * 缓存字段：
	 *  1、详情中：id与查询的where来确定
	 *  2、列表中：由查询的where来确定
	 *  3、删除缓存时，调用数据表设置的所有缓存字段来匹配操作
	 *
	 * 缓存绑定文件设置：
	 *  1、详情缓存保存：通过id与查询的where设置的字段来保存
	 *  2、详情缓存删除：通过id与查询的where设置的字段来保存
	 *  3、列表缓存保存：查询的where设置的字段来保存
	 *  4、列表缓存删除：查询的where设置的字段来保存
	 *
	 * 空数据的缓存与绑定
	 *  1、设置为空数据的缓存，一般是查询条件where的值
	 *  2、当查询数据为空的时候，用where与绑定字段进行绑定缓存
	 *
	 * 使用
	 *  1、添加：删除缓存
	 *  2、修改：删除缓存
	 *  3、列表：创建缓存
	 *  4、删除：删除缓存（一条记录，多条记录的删除）
	 *
	 */
	
	// 添加缓存与绑定
    // http://light/test/my-cache/lists
	public function add()
	{
		$cache = new BangCache();
		$model = new ContentBlogModel();
		$name  = $model->getName();  // 用于绑定
		
		// 缓存id 生成缓存文件
		$id        = 1;
		$field     = '*';
		$where     = [];
		$args      = compact('id', 'field', 'where');
		$cacheFile = $cache->getCacheFile($name, 'show', $args);

		
		// 获取数据
		$sqls = '';
		$info = $cache->getFile($cacheFile);
		if(empty($info)){
			$info = $model->oneFind(['id' => $id]);
			$sqls = $model->getLastSql();
			$cache->setFile($cacheFile, $info);
		}
		
		// 根据查询条件组合缓存绑定
		$fields = $this->queryField();
		$bangs  = $cache->makeInfoBangKey($info, $fields);
		foreach($bangs as $item){
			$bangFile = $cache->getBangFile($name, $item);
			$cache->setBang($bangFile, $cacheFile);
		}

        echo '第一次执行有sql，第二次执行没有sql';
		
		//$cache->delete($cacheFile);
		$result = ['sql' => $sqls, 'info' => $info,];
		
		
		return $this->success($result);
	}
	
	// 删除缓存文件以及其绑定文件
	public function delete()
	{
        $cache = new \app\service\BangCache();
		$model = new ContentBlogModel();
		$name  = $model->getName();  // 用于绑定
		
		// 缓存id 生成缓存文件
		$id        = 1;
		$field     = '*';
		$where     = [];
		$args      = compact('id', 'field', 'where');
		$cacheFile = $cache->getCacheFile($name, 'show', $args);
		
		// 获取数据
		$info = $model->oneFindCache(['id' => $id], ['id' => $id]);
		
		// 删除一条，测试成功
		// 根据表缓存字段组合缓存绑定
		$fields = $this->tableCacheField();
        $bangs = $cache->makeInfoBangKey($info, $fields);
        $cache->deleteAllBang($name, $bangs);

		// 删除多条记录，测试成功
		// 根据表缓存字段组合缓存绑定
		//$fields = $this->tableCacheField();
		//$cache->deleteListBang([$info], $name, $fields);
        echo '删除缓存后，重新查询，产生sql';
		
		return $this->success($model->getLastSql(), '删除缓存文件以及其绑定文件成功！');
	}
	
	// 列表缓存
	public function lists()
	{
		$cache = new BangCache();
		$model = new ContentBlogModel();
		$name  = $model->getName();  // 用于绑定
		
		// 测试
		$where = $bang = ['uid' => 80];
		$order = 'id ASC';
		
		// 默认测试
		$where = $bang = [];
		$order = 'id ASC';
		
		// 查询 生成缓存文件
		$page      = 1;
		$field     = '*';
		$rows      = 10;
		$args      = compact('where', 'field', 'page', 'rows', 'order');
		$cacheFile = $cache->getCacheFile($name, 'show', $args);
		
		// 获取数据
		$lists = $cache->getFile($cacheFile);
		if(empty($lists)){
			$lists = $model->listAll($where, $field, 1, $rows, $order);
			$cache->setFile($cacheFile, $lists);
		}
		
		// 根据查询条件组合缓存绑定
		$fields = $this->queryField();
        $bangs  = $model->makeInfoBangKey($bang, ['uid'], 'list');
		foreach($bangs as $item){
			$bangFile = $cache->getBangFile($name, $item);
			$cache->setBang($bangFile, $cacheFile);
		}

		
		echo '第一次执行有sql，第二次执行没有sql';
		$sqls   = $model->getLastSql();
		$result = ['sql' => $sqls, 'info' => $lists,];
		
		return $this->success($result);
	}
	
	// 重新缓存
	public function edit()
	{
		$id    = 1;
		$model = new ContentBlogModel();
		
		// 重新缓存
		$updata = ['title' => '修改直接更新缓存'];
		$model->updateCache($id, $updata);
		
		return $this->success($model->getLastSql(), '修改其他数据，删除列表缓存，删除详情缓存！');
	}
	
	##################################################################################
	// 查询时候的缓存字段
	protected function queryField()
	{
		return ['id', 'uid'];
	}
	
	// 数据表的缓存
	protected function tableCacheField()
	{
		return ['id', 'site_id', 'uid', 'company_id', 'top_id', 'event_id', 'poll_id', 'mtag_id', 'user_class_id', 'class_id', 'status',];
	}
	
}


